package AgentTravel.Behaviours;

import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.joda.time.LocalDate;

import AgentTravel.MyOntology;
import AgentTravel.LogicObjects.UserProfile;
import AgentTravel.Messages.DayGuestMessage;
import AgentTravel.Messages.RequestVisitMessage;
import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

public class HostGetReservationBehaviour extends Behaviour 
{
	//TODO: To powinno byc dla rozmowy z konkretnym, jednym visitorem
	
	private AID visitor;
	private List<LocalDate> dates;
	private Map<LocalDate,Boolean> available=new HashMap<LocalDate,Boolean>();
	private AID serverAgent;
	
	public HostGetReservationBehaviour(AID visitor, List<LocalDate> dates, AID serverAgent)
	{
		this.visitor=visitor;
		this.dates=dates;
		this.serverAgent=serverAgent;
	}
	
	private int step = 0;
	@Override
	public void action() 
	{
		switch (step) 
		{
			case 0:
				ACLMessage req=new ACLMessage(ACLMessage.REQUEST);
				req.addReceiver(visitor);
				req.setContent(MyOntology.requestProfileText);
				myAgent.send(req);
				step++;
				break;
			case 1:
				MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.INFORM_REF);
				mt=MessageTemplate.and(mt, MessageTemplate.MatchSender(visitor));
				
				ACLMessage msg = myAgent.receive(mt);
				
				if(msg!=null)
				{
					System.out.println("HOST: Dostalem profil visitora");
					try 
					{
						UserProfile hisProfile=(UserProfile)msg.getContentObject();
						if(MatchesPreferences(hisProfile))
						{
							System.out.println("HOST: Visitor Pasuje mi");
							System.out.println("HOST: Pytam serwera o dostepnosc");
							for(int i=0;i<dates.size();i++)
							{
								ACLMessage ava=new ACLMessage(ACLMessage.QUERY_IF);
								ava.addReceiver(serverAgent);
								try {
									ava.setContentObject(new DayGuestMessage(hisProfile,dates.get(i)));
									myAgent.send(ava);
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
								
							}
							step++;
						}
						else
						{
							System.out.println("HOST: Visitor Nie pasuje mi");
							
							ACLMessage neg=new ACLMessage(ACLMessage.INFORM);
							neg.addReceiver(visitor);
							neg.setContent(MyOntology.reservationAnswer);
							myAgent.send(neg);
							
							step=3;
							return;
						}
					} 
					catch (UnreadableException e) 
					{							
						e.printStackTrace();
					}
				}
				else
					block();
				
				
				break;
			case 2:
				//odbieramy od serwera info o tym czy mu pasuje
				MessageTemplate tm=MessageTemplate.MatchPerformative(ACLMessage.CONFIRM);
				tm=MessageTemplate.or(tm, MessageTemplate.MatchPerformative(ACLMessage.DISCONFIRM));
				tm=MessageTemplate.and(tm, MessageTemplate.MatchSender(serverAgent));
				
				ACLMessage inf = myAgent.receive(tm);
				
				if(inf!=null)
				{
					System.out.println("HOST: Server poinformowal mnie o dostepnosci dnia");
					try 
					{
						LocalDate cln=(LocalDate) inf.getContentObject();
						if(inf.getPerformative()==ACLMessage.CONFIRM)
						{
							available.put(cln, true);
						}
						else
						{
							available.put(cln, false);
						}
						System.out.println(available.size()+ " : "+dates.size());
						if(available.size()==dates.size())
							step++;
					} 
					catch (UnreadableException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				else
					block();
				break;
			case 3:
				ACLMessage reply=new ACLMessage(ACLMessage.INFORM);
				reply.addReceiver(visitor);
				String ansCnt=MyOntology.reservationAnswer;
				
				for(int i=0;i<dates.size();i++)
				{
					if(available.get(dates.get(i)))
						ansCnt+="_"+i+"_";
				}
				System.out.println("HOST: Wysylam: " + ansCnt);
				reply.setContent(ansCnt);
				
				myAgent.send(reply);
				step++;
				break;
		}		
	}
	
	private boolean MatchesPreferences(UserProfile hisProfile) 
	{
		//TODO: bullshit
		return true;
		
//		if(hisProfile.getAge()<myPreferences.getMinAge())
//			return false;
//		if(hisProfile.getAge()>myPreferences.getMaxAge())
//			return false;
//		
//		PreferredGender pg=myPreferences.getPreferredGender();
//		if(pg!=PreferredGender.Both &&
//				((pg==PreferredGender.Femal && hisProfile.getMyGender()==Gender.Male) || 
//				(pg==PreferredGender.Male && hisProfile.getMyGender()==Gender.Female)))
//			return false;
//		
//		boolean langOk=false;
//		for(int i=0;i<myPreferences.getAcceptableLanguages().size();i++)
//		{
//			if(hisProfile.getLanguages().
//					containsKey(myPreferences.getAcceptableLanguages().get(i)))
//				langOk=true;
//		}
//		
//		//TODO: chwilowo wylaczone
//		//if(!langOk)
//		//	return false;
//					
//		return true;
	}

	@Override
	public boolean done() 
	{
		
		return step==4;
	}

}
